((expr)=>{
    function getUUID() {
        var d = new Date().getTime();
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    }
    //长连接
    let transport={};
    transport.bg=()=>{
        let fn={};
        let callList={};
        let portList=[];
        let eventList={};
        //初始化
        chrome.runtime.onConnect.addListener((port)=>{
            portList.push(port);
            //监听
            let postMessage=port.postMessage;
            port._postMessage=(obj)=>{
                postMessage.call(port,obj);
            };
            port.postMessage=(key,info)=>{
                port._postMessage({key:key,message:info})
            };
            port.onMessage.addListener(function(info) {
                if(info.key && fn[info.key]){
                    fn[info.key](info.message,port,(data)=>{
                        info.cid && port._postMessage({cid:info.cid,message:data});
                    });
                }else if(info.cid && callList[info.cid]){
                    if(eventList['beforeResponse'] && eventList['beforeResponse'](info.message,port)===false){
                        return false;
                    }
                    callList[info.cid](info.message,port);
                    delete callList[info.cid];
                    eventList['afterResponse'] && eventList['afterResponse'](info.message,port);
                }
                eventList['after'] && eventList['after'](info.message,port);
            });
        });
        return {
            add(key,callback){
                if(typeof key ==="string"){
                    fn[key]=callback;
                }else if (typeof key ==="object"){
                    Object.keys(key).forEach((ky)=>{
                        fn[ky]=key[ky]
                    })
                }
            },
            rm(key){
                delete fn[key];
            },
            postMessage(key,info,callback){
                if(eventList['before'] && eventList['before'](key,info,callback,port)===false){
                    return false;
                }
                let cid=getUUID();
                callback && (callList[cid]=callback);
                portList.forEach((port,i)=>{
                    try{
                        if(callback){
                            port._postMessage({key:key,message:info,cid:cid});
                        }else{
                            port._postMessage({key:key,message:info});
                        }
                    }catch (e) {
                        //删除
                        portList.splice(i,1);
                    }
                })
            },
            on(eventName,callback){
                eventList[eventName]=callback;
            },
            un(eventName){
                delete eventList[eventName];
            }
        };
    };
    transport.cs=()=>{
        let fn={};
        let callList={};
        let eventList={};
        //初始化
        let port = chrome.runtime.connect({name:getUUID()});
        let postMessage=port.postMessage;
        port._postMessage=(obj)=>{
            postMessage.call(port,obj);
        };
        port.postMessage=(key,info)=>{
            port._postMessage({key:key,message:info})
        };
        port.onMessage.addListener(function(info) {
            if(info.key && fn[info.key]){
                fn[info.key](info.message,port,(data)=>{
                    info.cid && port._postMessage({cid:info.cid,message:data});
                });
            }else if(info.cid && callList[info.cid]){
                if(eventList['beforeResponse'] && eventList['beforeResponse'](info.message,port)===false){
                    return false;
                }
                callList[info.cid](info.message,port);
                delete callList[info.cid];
                eventList['afterResponse'] && eventList['afterResponse'](info.message,port);
            }
            eventList['after'] && eventList['after'](info.message,port);
        });
        return {
            add(key,callback){
                if(typeof key ==="string"){
                    fn[key]=callback;
                }else if (typeof key ==="object"){
                    Object.keys(key).forEach((ky)=>{
                        fn[ky]=key[ky]
                    })
                }
            },
            rm(key){
                delete fn[key];
            },
            postMessage(key,info,callback){
                if(eventList['before'] && eventList['before'](key,info,callback,port)===false){
                    return false;
                }
                if(callback){
                    let cid=getUUID();
                    callList[cid]=callback;
                    port._postMessage({key:key,message:info,cid:cid});
                }else{
                    port._postMessage({key:key,message:info});
                }
            },
            on(eventName,callback){
                eventList[eventName]=callback;
            },
            un(eventName){
                delete eventList[eventName];
            }
        };
    };
    expr.transport=transport;
})(window);